import {nextTick, ref, watch} from 'vue'
import {defineStore} from 'pinia'
import {cacheKeys} from '@/stores/constant/cacheKey'
import {map, remove} from 'lodash-es'
import type {MenuVO} from '@/model/route'

export const useNavTabsStore = defineStore(cacheKeys.NAV_TABS, () => {
			const activeIndex = ref(-1)
			const activeTab = ref<MenuVO>()
			const openedTabs = ref<MenuVO[]>([])
			const keepAliveTabNames = ref<MenuVO['meta']['fullPath'][]>([])
			const componentKey = ref<MenuVO['meta']['fullPath']>()
			const tabFullScreen = ref(false)

			watch(openedTabs, value => {
				// 方案1：使用el-tabs展示产线详情时，不需要特殊处理
				keepAliveTabNames.value = map(value.filter(menu => menu.meta.keepAlive), 'name')
				// 方案2：使用新标签页（动态路由）展示产线详情时，需要缓存产线详情标签页
				// keepAliveTabNames.value.length = 0
				// for (const menu of value) {
				// 	if (menu.meta.keepAlive) {
				// 		if (menu.name.startsWith('ProductionLineDetail_')) {
				// 			if (!keepAliveTabNames.value.includes('ProductionLineDetail')) {
				// 				keepAliveTabNames.value.push('ProductionLineDetail')
				// 			}
				// 		} else {
				// 			keepAliveTabNames.value.push(menu.name)
				// 		}
				// 	}
				// }
			}, {
				deep: true
			})

			const refreshTab = (menu: MenuVO = activeTab.value!) => {
				if (!menu) {
					return
				}
				const keepAlive = menu.meta.keepAlive
				// 将当前tab从缓存列表中删除，否则无法刷新
				if (keepAlive) {
					remove(keepAliveTabNames.value, componentName => componentName === activeTab.value!.name)
				}
				componentKey.value = undefined
				nextTick().then(() => {
					componentKey.value = menu.meta.fullPath
					// 将当前tab重新添加至缓存列表
					if (keepAlive) {
						keepAliveTabNames.value.push(menu.name)
					}
				})
			}

			function addTab(menu: MenuVO) {
				if (openedTabs.value.some(item => item.meta.fullPath === menu.meta.fullPath)) {
					return
				}
				openedTabs.value.push(menu)
			}

			/**
			 * 关闭一个标签
			 */
			function closeTab(menu: MenuVO) {
				openedTabs.value.map((v, k) => {
					if (v.meta.fullPath == menu.meta.fullPath) {
						openedTabs.value.splice(k, 1)
						return
					}
				})
			}

			/**
			 * 关闭左侧标签
			 */
			const closeLeftTabs = (menu?: MenuVO) => {
				const currentIndex = openedTabs.value.findIndex((item: MenuVO) => item.meta.fullPath === menu?.meta.fullPath)
				const retainedMenus: MenuVO[] = openedTabs.value.slice(currentIndex)
				for (let i = currentIndex - 1; i >= 0; i--) {
					// 固定标签不关闭
					if (openedTabs.value[i].meta.affix) {
						retainedMenus.unshift(openedTabs.value[i])
					}
				}
				openedTabs.value = retainedMenus
			}

			/**
			 * 关闭右侧标签
			 */
			const closeRightTabs = (menu?: MenuVO) => {
				const currentIndex = openedTabs.value.findIndex((item: MenuVO) => item.meta.fullPath === menu?.meta.fullPath)
				const retainedMenus: MenuVO[] = openedTabs.value.slice(0, currentIndex + 1)
				for (let i = currentIndex + 1; i < openedTabs.value.length; i++) {
					// 固定标签不关闭
					if (openedTabs.value[i].meta.affix) {
						retainedMenus.push(openedTabs.value[i])
					}
				}
				openedTabs.value = retainedMenus
			}

			/**
			 * 关闭多个标签
			 * @param retainedMenu 需要保留的标签，否则关闭全部标签
			 */
			const closeTabs = (retainedMenu?: MenuVO) => {
				const retainedMenus: MenuVO[] = []
				for (const menu of openedTabs.value) {
					// 需要保留的标签不关闭
					if (retainedMenu && menu.meta.fullPath === retainedMenu.meta.fullPath) {
						retainedMenus.push(menu)
						continue
					}
					// 固定标签不关闭
					if (menu.meta.affix) {
						retainedMenus.push(menu)
					}
				}
				openedTabs.value = retainedMenus
			}

			/**
			 * 关闭这些标签
			 * @param predicate 什么样的标签需要关闭
			 */
			const closeTheseTabs = (predicate: Predicate<MenuVO>) => {
				remove(openedTabs.value, predicate)
			}

			/**
			 * 保留这些标签，其余关闭
			 * @param predicate 什么样的标签需要保留
			 */
			const retainTheseTabs = (predicate: Predicate<MenuVO>) => {
				remove(openedTabs.value, value => !predicate(value))
			}

			const setActiveRoute = (menu: MenuVO): void => {
				const currentRouteIndex: number = openedTabs.value.findIndex((item: MenuVO) => {
					return item.meta.fullPath === menu.meta.fullPath
				})
				if (currentRouteIndex === -1) return
				activeTab.value = menu
				activeIndex.value = currentRouteIndex
			}

			const resetNavTabsStore = () => {
				activeIndex.value = -1
				activeTab.value = undefined
				openedTabs.value.length = 0
				tabFullScreen.value = false
			}

			return {
				activeIndex: activeIndex,
				activeTab: activeTab,
				openedTabs: openedTabs,
				keepAliveTabNames: keepAliveTabNames,
				componentKey: componentKey,
				tabFullScreen: tabFullScreen,
				refreshTab: refreshTab,
				addTab: addTab,
				closeTab: closeTab,
				closeLeftTabs: closeLeftTabs,
				closeRightTabs: closeRightTabs,
				closeTabs: closeTabs,
				closeTheseTabs: closeTheseTabs,
				retainTheseTabs: retainTheseTabs,
				setActiveRoute: setActiveRoute,
				resetNavTabsStore: resetNavTabsStore
			}
		},
		{
			persist: {
				key: cacheKeys.NAV_TABS,
				paths: ['activeIndex', 'activeRoute', 'openedTabs'],
				storage: window.sessionStorage
			}
		}
)
